package com.example.demo.generator.scaffold.registry;

import com.example.demo.generator.scaffold.model.TemplateContext;
import com.example.demo.generator.scaffold.model.TemplateDescriptor;
import com.example.demo.generator.scaffold.util.ScaffoldNameUtils;

import java.util.List;

/**
 * 生成可直接运行的 Spring Boot 工程骨架所需模板。
 */
public final class ProjectBootstrapTemplates {

    private ProjectBootstrapTemplates() {
    }

    public static List<TemplateDescriptor> all() {
        return List.of(
                pom(),
                applicationClass(),
                applicationYaml(),
                schemaSql(),
                baseResponse(),
                resultUtils(),
                errorCode(),
                businessException(),
                throwUtils(),
                globalExceptionHandler(),
                pageResponse()
        );
    }

    private static TemplateDescriptor pom() {
        return TemplateDescriptor.builder()
                .id("project-pom")
                .templatePath("scaffold/templates/backend/project/pom.ftl")
                .outputPathResolver(context -> resolveProjectRoot(context) + "/pom.xml")
                .build();
    }

    private static TemplateDescriptor applicationClass() {
        return TemplateDescriptor.builder()
                .id("project-application-class")
                .templatePath("scaffold/templates/backend/project/Application.ftl")
                .outputPathResolver(ProjectBootstrapTemplates::resolveApplicationPath)
                .build();
    }

    private static TemplateDescriptor applicationYaml() {
        return TemplateDescriptor.builder()
                .id("project-application-yaml")
                .templatePath("scaffold/templates/backend/project/application.yml.ftl")
                .outputPathResolver(context -> resolveProjectRoot(context) + "/src/main/resources/application.yml")
                .build();
    }

    private static TemplateDescriptor schemaSql() {
        return TemplateDescriptor.builder()
                .id("project-schema-sql")
                .templatePath("scaffold/templates/backend/project/schema.sql.ftl")
                .outputPathResolver(context -> resolveProjectRoot(context) + "/src/main/resources/schema.sql")
                .build();
    }

    private static TemplateDescriptor baseResponse() {
        return TemplateDescriptor.builder()
                .id("project-base-response")
                .templatePath("scaffold/templates/backend/project/common/BaseResponse.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "BaseResponse"))
                .build();
    }

    private static TemplateDescriptor resultUtils() {
        return TemplateDescriptor.builder()
                .id("project-result-utils")
                .templatePath("scaffold/templates/backend/project/common/ResultUtils.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "ResultUtils"))
                .build();
    }

    private static TemplateDescriptor errorCode() {
        return TemplateDescriptor.builder()
                .id("project-error-code")
                .templatePath("scaffold/templates/backend/project/common/ErrorCode.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "ErrorCode"))
                .build();
    }

    private static TemplateDescriptor businessException() {
        return TemplateDescriptor.builder()
                .id("project-business-exception")
                .templatePath("scaffold/templates/backend/project/common/BusinessException.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "BusinessException"))
                .build();
    }

    private static TemplateDescriptor throwUtils() {
        return TemplateDescriptor.builder()
                .id("project-throw-utils")
                .templatePath("scaffold/templates/backend/project/common/ThrowUtils.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "ThrowUtils"))
                .build();
    }

    private static TemplateDescriptor globalExceptionHandler() {
        return TemplateDescriptor.builder()
                .id("project-global-exception-handler")
                .templatePath("scaffold/templates/backend/project/common/GlobalExceptionHandler.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "GlobalExceptionHandler"))
                .build();
    }

    private static TemplateDescriptor pageResponse() {
        return TemplateDescriptor.builder()
                .id("project-page-response")
                .templatePath("scaffold/templates/backend/project/common/PageResponse.java.ftl")
                .outputPathResolver(context -> resolveCommonPath(context, "PageResponse"))
                .build();
    }

    private static String resolveApplicationPath(TemplateContext context) {
        String base = context.getBasePackage().replace('.', '/');
        String className = ScaffoldNameUtils.deriveApplicationClassName(context);
        return resolveProjectRoot(context) + "/src/main/java/" + base + "/" + className + ".java";
    }

    private static String resolveCommonPath(TemplateContext context, String className) {
        String base = context.getBasePackage().replace('.', '/');
        return resolveProjectRoot(context) + "/src/main/java/" + base + "/common/" + className + ".java";
    }

    private static String resolveProjectRoot(TemplateContext context) {
        return ScaffoldNameUtils.deriveArtifactId(context);
    }
}

